﻿using Inovout.Component;
using Inovout.Data.Service;
using Inovout.People.Domain;
using Inovout.People.Membership.Domain;
using Inovout.Security;

namespace Inovout.Membership.Security.OAuth.AuthorizationServer
{
    //Q 在实现类上打上ComponentAttribute即可自动注入，搜索下看看实现。
    [Inovout.Component.Component]
    public class CredentialValidator : ICredentialValidator
    {
        private IRepositoryService<MembershipUser> membershipUserService;

        public CredentialValidator()
        {
            membershipUserService = ComponentRegistry.Resolve<IRepositoryService<MembershipUser>>();
        }


        public IMembershipUser Validate(ICredential credential)
        {
            if (credential.GetType().Equals(typeof(IFormsCredential)))
            {
                return ValidateFormsCredential((IFormsCredential)credential);
            }
            else if (credential.GetType().Equals(typeof(DynamicPasswordCredential)))
            {
                return ValidateDynamicPasswordCredential((DynamicPasswordCredential)credential);
            }
            else if (credential.GetType().Equals(typeof(MailCredential)))
            {
                return ValidateMailCredential((MailCredential)credential);
            }

            return null;
        }


        private MembershipUser ValidateFormsCredential(IFormsCredential credentiaInfo)
        {
            FormsCredentialProvider formsCredentialProvider = new FormsCredentialProvider();
            FormsCredential formsCredential = formsCredentialProvider.Validate(credentiaInfo.UserName, credentiaInfo.Password);
            return formsCredential == null ? null : formsCredential.User;
        }


        private MembershipUser ValidateDynamicPasswordCredential(DynamicPasswordCredential credentiaInfo)
        {
            DynamicPasswordCredentialProvider dynamicPasswordCredentialProvider = new DynamicPasswordCredentialProvider();
            DynamicPasswordCredential dynamicPasswordCredential = dynamicPasswordCredentialProvider.Validate(credentiaInfo.Phone, credentiaInfo.Code);
            if (dynamicPasswordCredential == null)
            {
                return null;
            }
            return dynamicPasswordCredential.User ??
                    CreateMembershipUser(new Contact(ContactMethod.Mobile, dynamicPasswordCredential.Phone), dynamicPasswordCredential);
        }
        public MembershipUser ValidateMailCredential(IMailAuthenticationCredential credentiaInfo)
        {
            if (credentiaInfo.Domain.Equals("samples.cn"))
            {
                //验证凭据
                XMail263CredentialProvider credentialProvider = new XMail263CredentialProvider();
                var credential = credentialProvider.Validate(credentiaInfo);
                if (credential == null)
                {
                    return null;
                }
                //根据凭据中User属性判断是否为新MembershipUser
                return CreateMembershipUser(credentialProvider.GetPerson(credential.Mail), credential);
            }
            return null;
        }


        private MembershipUser CreateMembershipUser(Person person, ICredential credential)
        {
            MembershipCredential membershipCredential = credential as MembershipCredential;
            if (membershipCredential.User == null)
            {
                MembershipUser membershipUser = new MembershipUser();
                membershipUser.Credentials.Add(credential);
                membershipUser.Name = credential.Identity;
                PersonMembership membership = new PersonMembership(person);
                membershipUser.Membership = membership;
                membershipUserService.Save(membershipUser);
                return membershipUser;
            }
            else
            {
                return membershipCredential.User;
            }

        }
        private MembershipUser CreateMembershipUser(Contact contact, ICredential credential)
        {
            Person person = new Person();
            person.Contacts.Add(contact);

            return CreateMembershipUser(person, credential);
        }

        /// <summary>
        /// 发送动态验证码
        /// </summary>
        /// <param name="dynamicPassword"></param>
        public void SendDynamicPassword(DynamicPassword dynamicPassword)
        {
            DynamicPasswordMessage.SendTemplateSms(dynamicPassword.Phone, "JSM40576-0002", "@1@=" + dynamicPassword.Code);
        }
    }

}
